var common = angular.module('common', []);

common.directive("easySelect", function () {
    return {
        link: function (scope, element, attrs) {
            var ngModel = $(element).attr("ng-model");
            if (!ngModel || ngModel.length == 0) {
                ngModel = "defaultSelectModel";
            }

            if ($(element).attr('value')) {
                switch (ngModel.split('.').length) {
                    case 1 :
                        scope[ngModel] = $(element).attr('value');
                        break;
                    case 2 :
                        scope[ngModel.split('.')[0]][ngModel.split('.')[1]] = $(element).attr('value');
                        break;
                }
            }

            var status = false; //toggle boolean
            var valueMap = "";
            var options = $(element).children();
            $(element).attr("style", "padding:0");

            var optionMap = {};
            //hide original options
            $.each(options, function (opt) {
                optionMap[$(options[opt]).val()] = $(options[opt]).html();
                $(options[opt]).attr("style", "display:none");
            });

            //build ul
            var html = "<div id='" + attrs.id + "-root' style='width:100%;position: relative;left:-1px'>" +
                "<p id='display-" + attrs.id + "' style='padding:6px 12px " + ((attrs.multiple != undefined) ? "4px" : "7px") +
                " 12px;margin:0;border:none;width:95%;margin-left:2px;background-color: transparent'>" +
                "<span style='display: inline-block;padding-bottom: 3px'>&nbsp;</span></p>" +  //this is a dummy span
                "<ul id='" + attrs.id +
                "-container' class='list-group easy-select-container' style='display:none'>"; //options' container

            if (attrs.multiple != undefined) {
                $.each(options, function (opt) {
                    html += "<li value='" + $(options[opt]).val() + "' class='my-li-container list-group-item option-" +
                        attrs.id + "'><div style='width:100%;display:inline;position: relative;left:-14px;'>" + $(options[opt]).html() +
                        "</div><span value='" + $(options[opt]).val() + "' class='my-li-option glyphicon glyphicon-ok'></span></li>";
                });
            } else {
                $.each(options, function (opt) {
                    if ($(options[opt]).attr("default") != undefined) {
                        switch (ngModel.split('.').length) {
                            case 1 :
                                scope[ngModel] = $(options[opt]).val();
                                break;
                            case 2 :
                                scope[ngModel.split('.')[0]][ngModel.split('.')[1]] = $(options[opt]).val();
                                break;
                        }
                        valueMap = $(options[opt]).html();
                        html += "<li value='" + $(options[opt]).val() + "' class='my-li-container list-group-item option-" + attrs.id + "'>"
                            + $(options[opt]).html() + "</li>";
                    } else {
                        html += "<li value='" + $(options[opt]).val() + "' class='my-li-container list-group-item option-" + attrs.id + "'>"
                            + $(options[opt]).html() + "</li>";
                    }
                });
            }

            //if multiple, add button
            if (attrs.multiple != undefined) {
                html += "<li class='list-group-item ' for='ensure-li'><button class='btn btn-default'" +
                    " for='ensure-btn' style='padding: 2px' >&nbsp;&nbsp;确定&nbsp;&nbsp;</button></li>";
            }

            //render ui
            html += "</ul></div>";
            $(element).append(html);

            if ($(element).attr("value")) {
                $("#display-" + attrs.id).html("<span style='display: inline'>&nbsp;</span><span class='val-opt'>" +
                    optionMap[$(element).attr("value")] + "</span>");
            }

            $(".my-li-option").each(function () {
                $(this).fadeTo(0, 0.01);
            });

            if (attrs.multiple == undefined)
                $($("#display-" + attrs.id).children()[0]).html(valueMap);

            //adjust width
            $("#" + attrs.id + "-root").width($("#" + attrs.id + "-root").width() + 2);

            //mouse leave event
            $(element).mouseleave(function () {
                $(".my-li-container").each(function () {
                    $(this).attr("style", "");
                });
                if (status) {
                    $("#" + attrs.id + "-container").attr("style", "display:none");
                    status = !status;
                }
            });

            //multiple select seems complex
            if (attrs.multiple != undefined) {
                //click event
                $(element).click(function (e) {
                    //if click on tags, remove it
                    if ($(e.target).attr("for") == "option-tag") {
                        // change val and digest change item in angular
                        scope[ngModel] = $(element).val().replace($(e.target).attr("value"), "").replace(/;+/, ";").replace(/^;/, "");
                        $(element).val(scope[ngModel]);
                        scope.$digest();
                        $(".my-li-option").each(function () {
                            if ($(this).attr("value") == $(e.target).attr("value")) {
                                $(this).css("opacity", "0.01");
                            }
                        });
                        $(e.target).remove();
                    } else if ($(this).attr("for") != 'ensure-li') {
                        //toggle ul
                        $("#" + attrs.id + "-container").attr("style", status ? "display:none" : "");
                        status = !status;
                    }
                });

                $(".option-" + attrs.id).each(function () {
                    $(this).on('click', function () {
                        var selectValue = $(element).val();
                        var currentValue = $(this).attr("value");
                        var selected = false;
                        //if option is selected ,remove it
                        var temp = selectValue.split(";");
                        $.each(temp, function (obj) {
                            if (temp[obj].indexOf(currentValue) != -1) {
                                selected = true;
                            }
                        })
                        if (selected) {
                            $($(this).children()[1]).fadeTo(300, 0.01);
                            scope[ngModel] = $(element).val().replace(currentValue, "").replace(/;{2}/, ";").replace(/^;/, "");
                            $(element).val(scope[ngModel]);
                            scope.$digest();
                            $("#display-" + attrs.id + " span").each(function () {
                                if ($(this).attr("value") == currentValue) {
                                    $(this).remove();
                                }
                            });
                        } else {
                            //add option to val() and ui
                            $($(this).children()[1]).fadeTo(300, 1);
                            scope[ngModel] = ($(element).val() + ";" + currentValue).replace(/;{2}/, ";").replace(/^;/, "");
                            $(element).val(scope[ngModel]);
                            scope.$digest();
                            $("#display-" + attrs.id).append(
                                "<span for='option-tag' value='" + $(this).attr("value") + "' class='p-option-tag'>"
                                + $(this).children()[0].innerHTML + "</span>");
                        }
                        status = !status; // prevent bubble
                    });

                    //control background
                    $(this).mouseenter(function () {
                        $(".my-li-container").each(function () {
                            $(this).attr("style", "");
                        });
                        $(this).attr("style", "background-color:#eee");
                    });
                });
            } else {
                $(".option-" + attrs.id).each(function () {
                    $(this).mouseenter(function () {
                        $(".my-li-container").each(function () {
                            $(this).attr("style", "");
                        });
                        $(this).attr("style", "background-color:#eee");
                    });
                });
                //single select ,just add value and remove ul
                $(element).click(function () {
                    $("#" + attrs.id + "-container").attr("style", status ? "display:none" : "");
                    status = !status;
                });

                $(".option-" + attrs.id).each(function () {
                    $(this).on('click', function () {
                        switch (ngModel.split('.').length) {
                            case 1 :
                                scope[ngModel] = $(this).attr("value");
                                $(element).val(scope[ngModel]);
                                break;
                            case 2 :
                                scope[ngModel.split('.')[0]][ngModel.split('.')[1]] = $(this).attr("value");
                                $(element).val(scope[ngModel.split('.')[0]][ngModel.split('.')[1]]);
                                break;
                        }
                        scope.$digest();
                        $("#display-" + attrs.id).html("<span style='display: inline'>&nbsp;</span><span class='val-opt'>" + $(this).html() + "</span>");
                    });
                });
            }
        }
    }
});

common.directive("datetimepicker", function () {
    return {
        restrict: "EA",
        require: "ngModel",
        link: function (scope, element, attrs, ctrl) {
            var unregister = scope.$watch(function () {
                if (new Date(ctrl.$modelValue).valueOf() != 0) {
                    $(element).append("<input id='date-" + attrs.dateid + "' class='form-control' style='border:none;height:30px;' value='" + ctrl.$modelValue + "'>");
                } else {
                    $(element).append("<input id='date-" + attrs.dateid + "' class='form-control' style='border:none;height:30px;'>");
                }

                element.on('change', function () {
                    scope.$apply(function () {
                        ctrl.$setViewValue(new Date($("#date-" + attrs.dateid).val()).valueOf());
                    });
                });

                element.on('click', function () {
                    $("#date-" + attrs.dateid).datetimepicker({
                        format: attrs.format || 'Y/m/d h:i',
                        timepicker: false,
                        onClose: function () {
                            element.change();
                        }
                    });
                });

                element.click();

                return ctrl.$modelValue;
            }, initialize);

            function initialize(value) {
                ctrl.$setViewValue(value);
                unregister();
            }
        }
    }
});

common.directive("ace", function () {
    return {
        restrict: "EA",
        require: "ngModel",
        link: function (scope, element, attrs, ctrl) {
            var unregister = scope.$watch(function () {

                window.ace.require("language_tools");
                var editor = window.ace.edit("aceModalBody");
                editor.setOptions({
                    enableBasicAutocompletion: true,
                    enableSnippets: true,
                    enableLiveAutocompletion: true
                });

                $(element).click(function () {
                    $("#aceModalTitle").html("在线编辑");
                    editor.setValue(ctrl.$modelValue.entity[attrs.column].code);
                    editor.setTheme("ace/theme/clouds");
                    editor.getSession().setMode("ace/mode/javascript");
                    $("#aceModal").modal();

                    $("#aceSave").click(function () {
                        ctrl.$modelValue.entity[attrs.column].code = editor.getValue();
                        scope.col.colDef.onEditorSave(ctrl.$modelValue);
                    });
                });

                return ctrl.$modelValue;
            }, initialize);

            function initialize(value) {
                ctrl.$setViewValue(value);
                unregister();
            }
        }
    }
});

common.service("commonService", ['$http', function ($http) {

    Date.prototype.Format = function (fmt) {
        var o = {
            'M+': this.getMonth() + 1, //月份
            'd+': this.getDate(), //日
            'h+': this.getHours(), //小时
            'm+': this.getMinutes(), //分
            's+': this.getSeconds(), //秒
            'q+': Math.floor((this.getMonth() + 3) / 3), //季度
            'S': this.getMilliseconds()//毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
        return fmt;
    };

    Number.prototype.Format = function (decimals) {
        if (isNaN(this.valueOf())) {
            return 0
        }
        ;
        if (this.valueOf() == '') {
            return 0
        }
        ;

        var snum = new String(this.valueOf());
        var sec = snum.split('.');
        var whole = parseFloat(sec[0]);
        var result = '';

        if (sec.length > 1) {
            var dec = new String(sec[1]);
            dec = String(parseFloat(sec[1]) / Math.pow(10, (dec.length - decimals)));
            dec = String(whole + Math.round(parseFloat(dec)) / Math.pow(10, decimals));
            var dot = dec.indexOf('.');
            if (dot == -1) {
                dec += '.';
                dot = dec.indexOf('.');
            }
            while (dec.length <= dot + decimals) {
                dec += '0';
            }
            result = dec;
        } else {
            var dot;
            var dec = new String(whole);
            dec += '.';
            dot = dec.indexOf('.');
            while (dec.length <= dot + decimals) {
                dec += '0';
            }
            result = dec;
        }
        return result;
    }

    this.modalPrompt = function (msg, onConfirm) {
        if ($(".modal-prompt").length == 0) {
            $("body").append('<div class="modal fade  modal-prompt" style="position: absolute;top:40px;">\
            <div class="modal-dialog">\
            <div class="modal-content">\
            <div class="modal-header">\
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span\
            aria-hidden="true">&times;</span></button>\
            <h4 class="modal-confirm-title">' + msg + '</h4>\
            </div>\
            <div class="modal-body" style="height: 70px;">\
            <button type="button" class="btn btn-success col-md-2 pull-right" id="confirm-modal">确认</button>\
            <button type="button" class="btn btn-warning col-md-2 pull-right" style="margin-right: 20px"\
            data-dismiss="modal">取消\
            </button>\
            </div>\
            </div>\
            </div>\
            </div>');
            $(".modal-prompt").modal();
            $('#confirm-modal').unbind();
            $("#confirm-modal").click(function(e){
                $(".modal-prompt").modal("hide");
                onConfirm();
            });
        } else {
            $(".modal-confirm-title").html(msg);
            $(".modal-prompt").modal();
            $('#confirm-modal').unbind();
            $("#confirm-modal").click(function(e){
                $(".modal-prompt").modal("hide");
                onConfirm();
            });
        }
    };

    this.htmlencode = function (s) {
        var div = document.createElement('div');
        div.appendChild(document.createTextNode(s));
        return div.innerHTML;
    };
    this.htmldecode = function (s) {
        var div = document.createElement('div');
        div.innerHTML = s;
        return div.innerText || div.textContent;
    };
    return this;
}]);